home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / FX / fxrender.h < prev    next >
Text File  |  1999-02-04  |  8KB  |  366 lines

  1. /* -*- mode: C; tab-width:8;  -*-
  2.  
  3.              fxrender.h - 3Dfx VooDoo RenderVB driver function support
  4. */
  5.  
  6. /*
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Library General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Library General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Library General Public
  18.  * License along with this library; if not, write to the Free
  19.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  * See the file fxapi.c for more informations about authors
  22.  *
  23.  */
  24.  
  25. /************************************************************************/
  26. /************************ RenderVB function *****************************/
  27. /************************************************************************/
  28.  
  29. static GLboolean FXRENDERVB_NAME (GLcontext *ctx, GLboolean allDone)
  30. {
  31.   fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
  32.   struct vertex_buffer *VB=ctx->VB;
  33.   GLuint vlist[VB_SIZE];
  34.   GLenum prim=ctx->Primitive;
  35.  
  36.   /* Check if the cull front face mode is changed */
  37.  
  38.   if((ctx->Polygon.FrontFace!=fxMesa->currentFrontFace) &&
  39.      ctx->Polygon.CullFlag){
  40.     switch(ctx->Polygon.CullFaceMode) {
  41.     case GL_BACK:
  42.       if(ctx->Polygon.FrontFace==GL_CCW)
  43.     grCullMode(GR_CULL_NEGATIVE);
  44.       else
  45.     grCullMode(GR_CULL_POSITIVE);
  46.       break;
  47.     case GL_FRONT:
  48.       if(ctx->Polygon.FrontFace==GL_CCW)
  49.     grCullMode(GR_CULL_POSITIVE);
  50.       else
  51.     grCullMode(GR_CULL_NEGATIVE);
  52.       break;
  53.     case GL_FRONT_AND_BACK:
  54.       grCullMode(GR_CULL_DISABLE);
  55.       (*ctx->Driver.UpdateState)(ctx);
  56.       return GL_FALSE;
  57.     default:
  58.       /* do nothing */
  59.       break;
  60.     }
  61.  
  62.     fxMesa->currentFrontFace=ctx->Polygon.FrontFace;
  63.   }
  64.  
  65.   /* A small optimization for GLQuake */
  66.  
  67.   if(prim==GL_POLYGON) {
  68.     if(VB->Count==3)
  69.       prim=GL_TRIANGLES;
  70.     else if(VB->Count==4)
  71.       prim=GL_QUADS;
  72.   }
  73.  
  74.   switch (prim) {
  75.   case GL_POINTS:
  76.     (*ctx->Driver.PointsFunc)(ctx,0,VB->Count-1);
  77.     break;
  78.  
  79.   case GL_LINES:
  80.     if(VB->ClipOrMask) {
  81.       GLuint i;
  82.       GrVertex *gWin=fxMesa->gWin;
  83.  
  84.       for(i=1;i<VB->Count;i+=2,gWin+=2) {
  85.     RVB_COLOR(i);
  86.  
  87.     if (VB->ClipMask[i-1] | VB->ClipMask[i]) {
  88.       fxRenderClippedLine(ctx,i-1,i);
  89.     } else
  90.       grDrawLine(&gWin[0],&gWin[1]);
  91.  
  92.     ctx->StippleCounter = 0;
  93.       }
  94.     } else {
  95.       GLuint i;
  96.       GrVertex *gWin=fxMesa->gWin;
  97.  
  98.       for(i=1;i<VB->Count;i+=2,gWin+=2) {
  99.     RVB_COLOR(i);
  100.     grDrawLine(&gWin[0],&gWin[1]);
  101.  
  102.     ctx->StippleCounter=0;
  103.       }
  104.     }
  105.     break;
  106.  
  107.   case GL_LINE_STRIP:
  108.     if(VB->ClipOrMask) {
  109.       GLuint i;
  110.       GrVertex *gWin=fxMesa->gWin;
  111.  
  112.       for(i=1;i<VB->Count;i++,gWin++) {
  113.     RVB_COLOR(i);
  114.  
  115.     if(VB->ClipMask[i-1] | VB->ClipMask[i])
  116.       fxRenderClippedLine(ctx,i-1,i);
  117.     else
  118.       grDrawLine(&gWin[0],&gWin[1]);
  119.       }
  120.     } else {
  121.       /* no clipping needed */
  122.       GLuint i;
  123.       GrVertex *gWin=fxMesa->gWin;
  124.       
  125.       for(i=1;i<VB->Count;i++,gWin++) {
  126.     RVB_COLOR(i);
  127.     grDrawLine(&gWin[0],&gWin[1]);
  128.       }   
  129.     }
  130.     break;
  131.  
  132.   case GL_LINE_LOOP:
  133.     {
  134.       GLuint i;
  135.       GrVertex *gWin;
  136.  
  137.       if(VB->Start==0) {
  138.     i=1;  /* start at 0th vertex */
  139.     gWin=fxMesa->gWin;
  140.       } else {
  141.     i=2;  /* skip first vertex, we're saving it until glEnd */
  142.     gWin=&fxMesa->gWin[1];
  143.       }
  144.  
  145.       while(i<VB->Count) {
  146.     RVB_COLOR(i);
  147.     
  148.     if(VB->ClipMask[i-1] | VB->ClipMask[i])
  149.       fxRenderClippedLine(ctx,i-1,i);
  150.     else
  151.       grDrawLine(&gWin[0],&gWin[1]);
  152.  
  153.     i++;
  154.     gWin++;
  155.       }
  156.     }
  157.   break;
  158.  
  159.   case GL_TRIANGLES:
  160.     if(VB->ClipOrMask) {
  161.       GLuint i;
  162.       GrVertex *gWin=fxMesa->gWin;
  163.  
  164.       for(i=2;i<VB->Count;i+=3,gWin+=3) {
  165.     if(VB->ClipMask[i-2] | VB->ClipMask[i-1] | VB->ClipMask[i]) {
  166.       vlist[0]=i-2;
  167.       vlist[1]=i-1;
  168.       vlist[2]=i-0;
  169.       RVB_COLOR(i);
  170.       fxRenderClippedPolygon(ctx,3,vlist);
  171.     } else {
  172.       RVB_COLOR(i);
  173.       grDrawTriangle(&gWin[0],&gWin[1],&gWin[2]);
  174.     }
  175.       }
  176.     } else {
  177.       GLuint i;
  178.       GrVertex *gWin=fxMesa->gWin;
  179.  
  180.       for(i=2;i<VB->Count;i+=3,gWin+=3) {
  181.     RVB_COLOR(i);
  182.     grDrawTriangle(&gWin[0],&gWin[1],&gWin[2]);
  183.       }
  184.     }
  185.     break;
  186.  
  187.   case GL_TRIANGLE_STRIP:
  188.     if (VB->ClipOrMask) {
  189.       GLuint i;
  190.       GrVertex *gWin=fxMesa->gWin;
  191.  
  192.       for(i=2;i<VB->Count;i++,gWin++) {
  193.     RVB_COLOR(i);
  194.     
  195.     if(VB->ClipMask[i-2] | VB->ClipMask[i-1] | VB->ClipMask[i]) {
  196.       if(i&1) {
  197.         /* reverse vertex order */
  198.         vlist[0]=i-1;
  199.         vlist[1]=i-2;
  200.         vlist[2]=i-0;
  201.         fxRenderClippedPolygon(ctx,3,vlist);
  202.       } else {
  203.         vlist[0]=i-2;
  204.         vlist[1]=i-1;
  205.         vlist[2]=i-0;
  206.         fxRenderClippedPolygon(ctx,3,vlist);
  207.       }
  208.     } else {
  209.       if(i&1)
  210.         grDrawTriangle(&gWin[2],&gWin[1],&gWin[0]);
  211.       else
  212.         grDrawTriangle(&gWin[0],&gWin[1],&gWin[2]);
  213.     }
  214.       }
  215.     } else {
  216.       GLuint i;
  217.       GrVertex *gWin=fxMesa->gWin;
  218.           
  219.       for(i=2;i<VB->Count;i++,gWin++) {
  220.     RVB_COLOR(i);
  221.  
  222.     if(i&1)
  223.       grDrawTriangle(&gWin[2],&gWin[1],&gWin[0]);
  224.     else
  225.       grDrawTriangle(&gWin[0],&gWin[1],&gWin[2]);
  226.       }
  227.     }
  228.     break;
  229.  
  230.   case GL_TRIANGLE_FAN:
  231.     if (VB->ClipOrMask) {
  232.       GLuint i;
  233.       GrVertex *gWin,*gstart;
  234.  
  235.       gstart=fxMesa->gWin;
  236.       gWin=&fxMesa->gWin[1];
  237.  
  238.       for(i=2;i<VB->Count;i++,gWin++) {
  239.     RVB_COLOR(i);
  240.  
  241.     if (VB->ClipMask[0] | VB->ClipMask[i-1] | VB->ClipMask[i]) {
  242.       vlist[0]=0;
  243.       vlist[1]=i-1;
  244.       vlist[2]=i;
  245.       fxRenderClippedPolygon(ctx,3,vlist);
  246.     } else
  247.       grDrawTriangle(gstart,&gWin[0],&gWin[1]);
  248.       }
  249.     } else {
  250.       /* no clipping needed */
  251.       GLuint i;
  252.       GrVertex *gWin,*gstart;
  253.  
  254.       gstart=fxMesa->gWin;
  255.       gWin=&fxMesa->gWin[1];
  256.  
  257.       for(i=2;i<VB->Count;i++,gWin++) {
  258.     RVB_COLOR(i);
  259.     grDrawTriangle(gstart,&gWin[0],&gWin[1]);
  260.       }
  261.     }
  262.     break;
  263.  
  264.   case GL_QUADS:
  265.     if (VB->ClipOrMask) {
  266.       GLuint i;
  267.       GrVertex *gWin=fxMesa->gWin;
  268.  
  269.       for (i=3;i<VB->Count;i+=4,gWin+=4) {
  270.     RVB_COLOR(i);
  271.  
  272.     if(VB->ClipMask[i-3] | VB->ClipMask[i-2]
  273.        | VB->ClipMask[i-1] | VB->ClipMask[i]) {
  274.       vlist[0]=i-3;
  275.       vlist[1]=i-2;
  276.       vlist[2]=i-1;
  277.       vlist[3]=i-0;
  278.       fxRenderClippedPolygon(ctx,4,vlist);
  279.     } else {
  280.       grDrawTriangle(&gWin[0],&gWin[1],&gWin[3]);
  281.       grDrawTriangle(&gWin[1],&gWin[2],&gWin[3]);
  282.     }
  283.       }
  284.     } else {
  285.       /* no vertices were clipped */
  286.       GLuint i;
  287.       GrVertex *gWin=fxMesa->gWin;
  288.  
  289.       for(i=3;i<VB->Count;i+=4,gWin+=4) {
  290.     RVB_COLOR(i);
  291.     grDrawTriangle(&gWin[0],&gWin[1],&gWin[3]);
  292.     grDrawTriangle(&gWin[1],&gWin[2],&gWin[3]);
  293.       }
  294.     }
  295.     break;
  296.  
  297.   case GL_QUAD_STRIP:
  298.     if (VB->ClipOrMask) {
  299.       GLuint i;
  300.       GrVertex *gWin=fxMesa->gWin;
  301.  
  302.       for(i=3;i<VB->Count;i+=2,gWin+=2) {
  303.     RVB_COLOR(i);
  304.  
  305.     if(VB->ClipMask[i-2] | VB->ClipMask[i-3]
  306.        | VB->ClipMask[i-1] | VB->ClipMask[i]) {
  307.       vlist[0]=i-1;
  308.       vlist[1]=i-3;
  309.       vlist[2]=i-2;
  310.       vlist[3]=i-0;
  311.       fxRenderClippedPolygon(ctx,4,vlist);
  312.     } else {
  313.       grDrawTriangle(&gWin[0],&gWin[1],&gWin[2]);
  314.       grDrawTriangle(&gWin[1],&gWin[3],&gWin[2]);
  315.     }
  316.       }
  317.     } else {
  318.       /* no clipping needed */
  319.       GLuint i;
  320.       GrVertex *gWin=fxMesa->gWin;
  321.       
  322.       for(i=3;i<VB->Count;i+=2,gWin+=2) {
  323.     RVB_COLOR(i);
  324.     grDrawTriangle(&gWin[0],&gWin[1],&gWin[2]);
  325.     grDrawTriangle(&gWin[1],&gWin[3],&gWin[2]);
  326.       }
  327.     }
  328.     break;
  329.  
  330.   case GL_POLYGON:
  331.     if (VB->Count>2) {
  332.       if (VB->ClipAndMask & CLIP_ALL_BITS) {
  333.     /* all points clipped by common plane, draw nothing */
  334.     break;
  335.       }
  336.  
  337.       RVB_COLOR(0);
  338.  
  339.       if(VB->ClipOrMask) {
  340.     GLuint i;
  341.  
  342.     for(i=0;i<VB->Count;i++)
  343.       vlist[i]=i;
  344.  
  345.     fxRenderClippedPolygon(ctx,VB->Count,vlist);
  346.       } else {
  347.     fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
  348.     GrVertex *gWin=fxMesa->gWin;
  349.     GLint i;
  350.  
  351.     for (i=2;i<VB->Count;i++)
  352.       grDrawTriangle(&gWin[0],&gWin[i-1],&gWin[i]);
  353.       }
  354.     }
  355.     break;
  356.  
  357.   default:
  358.     /* should never get here */
  359.     gl_problem(ctx,"invalid mode in gl_render_vb");
  360.   }
  361.  
  362.   gl_reset_vb(ctx,allDone);
  363.  
  364.   return GL_TRUE;
  365. }
  366.